1,其实早就想把这些东西给封装封装的,一直没有时间,今天刚好项目进入到测试阶段了,Bug同事在哪儿测试的飞起,但发现提bug的尽然是我(得意脸),然后上午把ios的包测试了一下,顺便把服务器给测挂了(别问我是怎么做到的),现在服务器的同事还在拿着刀满街找我呐。好了不扯了,就想标题写了,一直想把这一块揉在一起写写,那就趁这个机会吧。
先看看今天我们要实现的效果:
2,有些童鞋就很气愤了,麻蛋,裤子都脱了,你给我看这个!!!!
其实我也想多写点的啊,还想把App下载写上呢,没事,我们慢慢一点点的来,,先来看一下我们接口的数据吧
1
2
3
4
5
6
7
8
9
|
{
"code"
:
200
,
"message"
:
""
,
"data"
: {
"code"
:
"1.1.0"
,
"size"
:
"8.6M"
,
"des"
:
"1.【新增】自动更新\\r\\n2.【修改】部分ProgressBar替换为SVG\\r\\n3.【修改】Gank板块部分改动\\r\\n"
}
}
|
可以看到,这是一个标准的接口数据,外部包含 code、message、data三大门神,这样我们封装Response就很好解决了。
看一下我们的BaseResponse类,很简单,没有什么讲的
BaseResponse.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package
com.qianmo.myview2.response;
/**
* Created by wangjitao on 2016/11/8 0008.
* 数据返回类类
*/
public
class
BaseResponse<T> {
private
int
code;
private
String message;
private
T data;
public
T getData() {
return
data;
}
public
void
setData(T data) {
this
.data = data;
}
public
String getMessage() {
return
message;
}
public
void
setMessage(String message) {
this
.message = message;
}
public
int
getCode() {
return
code;
}
public
void
setCode(
int
code) {
this
.code = code;
}
}
|
再看一下我们这次的功能,就是一个简单的网络请求,判断当前app版本和服务器上的版本,从而判断是否是最新的,看到这里的同学可能就很疑惑了,麻蛋,不是说好了是封装封装嘛,为什么到现在还在说功能,嗯,阿呆哥哥只是想从本质上对比一下如果我们使用传统的MVC去写的话该是怎么写的啊,相信现在很多同学已经在脑海中已经有了代码了,不过我猜你们的Activity中的代码会很多(奸笑脸),好吧,我前面的博客也介绍了MVP模式,现在我们是要把MVP运用在项目里面,所以,我们就要开始封装基类了!!
3 ,封装
①BaseView
我们知道在MVP模式中我们的V是和我们用户界面的UI有关的,不管是控件的隐藏和显示,还是控件大小的改变都是我们的V来处理的,所以这里我们只是写了个简单的夜间模式的UI改变的方法、还有展示错误信息的方法,很简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
com.qianmo.myview2.base;
import
android.view.View;
/**
* Created by wangjitao on 2016/11/8 0008.
* 一般的Activity中要用到View操作无非是显示加载框、影藏加载框、显示出错信息、显示当数据为空的时候的view之类的
*/
public
interface
BaseView {
void
showError(String msg);
void
useNightMode(
boolean
isNight);
}
|
②BasePresenter
P在MVP架构中是主要用于逻辑处理的,所以一是我们最经常要写的,看一下代码,就是AttachView和DetachView(这也没什么好解释的)
1
2
3
4
5
6
7
8
9
10
11
12
|
package
com.qianmo.myview2.base;
/**
* Created by wangjitao on 2016/11/8 0008.
* MVP框架的简单封装 P处理层
*/
public
interface
BasePresenter<T
extends
BaseView> {
void
attachView(T view);
void
detachView();
}
|
③App
这个类一般用于初始化一些数据,如屏幕的信息之类的和Activity的简单的管理啊,还有一些第三方SDK的初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
package
com.qianmo.myview2;
import
android.app.Activity;
import
android.app.Application;
import
android.content.Context;
import
android.util.DisplayMetrics;
import
android.view.Display;
import
android.view.WindowManager;
import
java.util.HashSet;
import
java.util.Set;
/**
* Created by wangjitao on 2016/11/8 0008.
*/
public
class
App
extends
Application {
private
static
App instance;
private
Set<Activity> allActivities;
public
static
int
SCREEN_WIDTH = -
1
;
public
static
int
SCREEN_HEIGHT = -
1
;
public
static
float
DIMEN_RATE = -
1
.0F;
public
static
int
DIMEN_DPI = -
1
;
public
static
synchronized
App getInstance() {
return
instance;
}
@Override
public
void
onCreate() {
super
.onCreate();
instance =
this
;
getScreenSize();
}
/**
* 初始化屏幕宽高
*/
public
void
getScreenSize() {
WindowManager windowManager = (WindowManager)
this
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm =
new
DisplayMetrics();
Display display = windowManager.getDefaultDisplay();
display.getMetrics(dm);
DIMEN_RATE = dm.density /
1
.0F;
DIMEN_DPI = dm.densityDpi;
SCREEN_WIDTH = dm.widthPixels;
SCREEN_HEIGHT = dm.heightPixels;
if
(SCREEN_WIDTH > SCREEN_HEIGHT) {
int
t = SCREEN_HEIGHT;
SCREEN_HEIGHT = SCREEN_WIDTH;
SCREEN_WIDTH = t;
}
}
/**
* 添加activity
*/
public
void
addActivity(Activity act) {
if
(allActivities ==
null
) {
allActivities =
new
HashSet<>();
}
allActivities.add(act);
}
/**
* 移除activity
*/
public
void
removeActivity(Activity act) {
if
(allActivities !=
null
) {
allActivities.remove(act);
}
}
/**
* 退出app
*/
public
void
exitApp() {
if
(allActivities !=
null
) {
synchronized
(allActivities) {
for
(Activity act : allActivities) {
act.finish();
}
}
}
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(
0
);
}
/**
* 这还有一系列的第三方SDK的初始化
*/
}
|
④BaseActivity
这个貌似是最重要的,这里我们考虑到5.0一下的机器切换Activity比较丑,所以写了下切换的动画,,然后就是一系列的初始化,直接贴出来吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
package
com.qianmo.myview2.base;
import
android.app.Activity;
import
android.os.Bundle;
import
android.support.annotation.Nullable;
import
android.support.v7.app.AppCompatActivity;
import
android.support.v7.widget.Toolbar;
import
android.view.View;
import
com.qianmo.myview2.App;
import
com.qianmo.myview2.R;
import
butterknife.Unbinder;
import
butterknife.ButterKnife;
/**
* Created by wangjitao on 2016/11/8 0008.
* 基类Activity的封装
* 一般使用mvp模式的话会在BaseActivity中进行P和V的初始化绑定
*/
public
abstract
class
BaseActivity<T
extends
BasePresenter>
extends
AppCompatActivity
implements
BaseView {
protected
T mPresenter;
protected
Activity mContext;
private
Unbinder mUnbinder;
public
enum
TransitionMode {
LEFT, RIGHT, TOP, BOTTOM, SCALE, FADE
}
protected
void
onCreate(
@Nullable
Bundle savedInstanceState) {
if
(toggleOverridePendingTransition()) {
switch
(getOverridePendingTransitionMode()) {
case
LEFT:
overridePendingTransition(R.anim.left_in, R.anim.left_out);
break
;
case
RIGHT:
overridePendingTransition(R.anim.right_in, R.anim.right_out);
break
;
case
TOP:
overridePendingTransition(R.anim.top_in, R.anim.top_out);
break
;
case
BOTTOM:
overridePendingTransition(R.anim.bottom_in, R.anim.bottom_out);
break
;
case
SCALE:
overridePendingTransition(R.anim.scale_in, R.anim.scale_out);
break
;
case
FADE:
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
break
;
}
}
super
.onCreate(savedInstanceState);
setContentView(getLayout());
mUnbinder = ButterKnife.bind(
this
);
mContext =
this
;
createPresenter();
if
(mPresenter !=
null
)
mPresenter.attachView(
this
);
App.getInstance().addActivity(
this
);
initEventAndData();
}
@Override
protected
void
onStart() {
super
.onStart();
}
@Override
protected
void
onDestroy() {
super
.onDestroy();
if
(mPresenter !=
null
)
mPresenter.detachView();
mUnbinder.unbind();
App.getInstance().removeActivity(
this
);
}
protected
void
setToolBar(Toolbar toolbar, String title) {
toolbar.setTitle(title);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(
true
);
getSupportActionBar().setDisplayShowHomeEnabled(
true
);
toolbar.setNavigationOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View view) {
onBackPressed();
}
});
}
protected
abstract
int
getLayout();
protected
abstract
void
initEventAndData();
protected
abstract
boolean
toggleOverridePendingTransition();
protected
abstract
TransitionMode getOverridePendingTransitionMode();
protected
abstract
void
createPresenter();
}
|
⑤ BaseRecyclerViewAdapter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
package
com.qianmo.myview2.base;
import
android.content.Context;
import
android.support.v7.widget.RecyclerView;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
com.balysv.materialripple.MaterialRippleLayout;
import
com.qianmo.myview2.R;
import
java.util.List;
/**
* Created by wangjitao on 2016/11/7 0007.
* 对简单的recycleview进行简单的封装
*/
public
abstract
class
BaseRecyclerViewAdapter<T>
extends
RecyclerView.Adapter<BaseViewHolder> {
private
Context context;
private
LayoutInflater inflater;
private
List<T> datas;
private
int
layoutId;
protected
OnItemClickListner onItemClickListner;
//单击事件
protected
OnItemLongClickListner onItemLongClickListner;
//长按单击事件
private
boolean
clickFlag =
true
;
//单击事件和长单击事件的屏蔽标识
public
BaseRecyclerViewAdapter(Context context, List<T> datas,
int
layoutId) {
this
.context = context;
this
.datas = datas;
this
.layoutId = layoutId;
this
.inflater = LayoutInflater.from(context);
}
@Override
public
BaseViewHolder onCreateViewHolder(ViewGroup parent,
int
viewType) {
BaseViewHolder holder =
new
BaseViewHolder(inflater.inflate(layoutId, parent,
false
));
MaterialRippleLayout.on(holder.getView(R.id.ll_all))
.rippleOverlay(
true
)
.rippleAlpha(
0
.2f)
.rippleColor(context.getResources().getColor(R.color.colorAccent))
.rippleHover(
true
)
.create();
return
holder;
}
@Override
public
void
onBindViewHolder(BaseViewHolder holder,
int
position) {
bindData(holder, datas.get(position), position);
}
@Override
public
int
getItemCount() {
return
datas ==
null
?
0
: datas.size();
}
protected
abstract
void
bindData(BaseViewHolder holder, T data,
int
position);
public
void
setOnItemClickListner(OnItemClickListner onItemClickListner) {
this
.onItemClickListner = onItemClickListner;
}
public
void
setOnItemLongClickListner(OnItemLongClickListner onItemLongClickListner) {
this
.onItemLongClickListner = onItemLongClickListner;
}
public
interface
OnItemClickListner {
void
onItemClickListner(View v,
int
position);
}
public
interface
OnItemLongClickListner {
void
onItemLongClickListner(View v,
int
position);
}
}
|
⑥ BaseViewHolder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package
com.qianmo.myview2.base;
import
android.support.v7.widget.RecyclerView;
import
android.util.SparseArray;
import
android.view.View;
/**
* Created by wangjitao on 2016/11/7 0007.
* 万能的Viewholder
*/
public
class
BaseViewHolder
extends
RecyclerView.ViewHolder {
private
SparseArray<View> views;
public
BaseViewHolder(View view) {
super
(view);
this
.views =
new
SparseArray<>();
}
public
<T
extends
View> T getView(
int
viewId) {
View view = views.get(viewId);
if
(view ==
null
) {
view = itemView.findViewById(viewId);
views.put(viewId, view);
}
return
(T) view;
}
public
View getRootView() {
return
itemView;
}
}
|
由于上一篇介绍了怎么封装RecycleView的Adapter,在这里就不在废话了
4,好了东西都封装好了,看一下我们在实际功能中怎么写吧,由于我们上面的功能,我们要实现一个简单的版本判断,由于要使用网络,这里我打算使用Retrofit+RxJava,但是还没有封装好,就直接拿没封装的直接用了,这里创建mvp模式的话要创建好多个接口啊 ,所以推荐是用MVPHelper这个插件,挺好用的 ,好了,先看一下我们的MainContract
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package
com.qianmo.myview2.contract;
import
com.qianmo.myview2.base.BasePresenter;
import
com.qianmo.myview2.base.BaseView;
import
com.qianmo.myview2.bean.VersionBean;
/**
* Created by wangjitao on 2016/11/8 0008.
* 首页逻辑处理
*/
public
class
MainContract {
public
interface
View
extends
BaseView {
//View效果就是展示下载进度框
void
showUpdateDialog(VersionBean bean);
void
showProgressDialog();
void
DissProgressDialog();
void
ShowToast(String message);
}
public
interface
Presenter
extends
BasePresenter<View> {
//一般在首页我们会进行一个版本的更新(功能)
void
checkVersion(String currentVersion);
}
}
|
就只是接口的常见,并把这次功能要用到的方法全部抽象出来,
看一下我们Presenter的实现类
MainPresenterImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
package
com.qianmo.myview2.presenter;
import
android.widget.Toast;
import
com.qianmo.myview2.CheckVersionActivity;
import
com.qianmo.myview2.MainActivity;
import
com.qianmo.myview2.api.AppVersionService;
import
com.qianmo.myview2.bean.VersionBean;
import
com.qianmo.myview2.contract.MainContract;
import
com.qianmo.myview2.response.BaseResponse;
import
com.qianmo.myview2.utils.Constant;
import
retrofit2.Retrofit;
import
retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import
retrofit2.converter.gson.GsonConverterFactory;
import
rx.Subscriber;
import
rx.android.schedulers.AndroidSchedulers;
import
rx.schedulers.Schedulers;
/**
* Created by MVPHelper on 2016/11/08
*/
public
class
MainPresenterImpl
implements
MainContract.Presenter {
private
MainContract.View mView;
@Override
public
void
checkVersion(
final
String currentVersion) {
Retrofit retrofit =
new
Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
AppVersionService movieService = retrofit.create(AppVersionService.
class
);
movieService.getVersion()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new
Subscriber<BaseResponse<VersionBean>>() {
@Override
public
void
onStart() {
mView.showProgressDialog();
}
@Override
public
void
onCompleted() {
mView.DissProgressDialog();
}
@Override
public
void
onError(Throwable e) {
mView.DissProgressDialog();
mView.ShowToast(
"请求出错"
);
}
@Override
public
void
onNext(BaseResponse<VersionBean> versionBeanBaseResponse) {
if
(Integer.valueOf(currentVersion.replace(
"."
,
""
)) < Integer.valueOf(versionBeanBaseResponse.getData().getCode().replace(
"."
,
""
))) {
// mView.showUpdateDialog(versionBean);
//这里表示发现新版本
mView.ShowToast(
"发现最新版本"
);
}
else
{
//表示这就是最新版本
mView.ShowToast(
"已经是最新版本"
);
}
}
});
}
@Override
public
void
attachView(MainContract.View view) {
mView = view;
}
@Override
public
void
detachView() {
mView =
null
;
}
}
|
没有什么好讲解的,其实还可以把presenter层封装一下的,可以在封装成这样的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public
class
BasePresenter<T
extends
MvpView>
implements
Presenter<T> {
private
T mMvpView;
@Override
public
void
attachView(T mvpView) {
mMvpView = mvpView;
}
@Override
public
void
detachView() {
mMvpView =
null
;
}
public
boolean
isViewAttached() {
return
mMvpView !=
null
;
}
public
T getMvpView() {
return
mMvpView;
}
public
void
checkViewAttached() {
if
(!isViewAttached())
throw
new
MvpViewNotAttachedException();
}
public
static
class
MvpViewNotAttachedException
extends
RuntimeException {
public
MvpViewNotAttachedException() {
super
(
"Please call Presenter.attachView(MvpView) before"
+
" requesting data to the Presenter"
);
}
}
}
|
ok,最后看一下我们的Activity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
package
com.qianmo.myview2;
import
android.content.pm.PackageInfo;
import
android.content.pm.PackageManager;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.Button;
import
android.widget.ProgressBar;
import
android.widget.Toast;
import
com.qianmo.myview2.base.BaseActivity;
import
com.qianmo.myview2.bean.VersionBean;
import
com.qianmo.myview2.contract.MainContract;
import
com.qianmo.myview2.presenter.MainPresenterImpl;
import
butterknife.BindView;
public
class
CheckVersionActivity
extends
BaseActivity<MainPresenterImpl>
implements
MainContract.View, View.OnClickListener {
@BindView
(R.id.btn_getVersion)
Button btnGetVersion;
@BindView
(R.id.progressBar)
ProgressBar progressBar;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
}
@Override
protected
int
getLayout() {
return
R.layout.activity_main;
}
@Override
protected
void
initEventAndData() {
btnGetVersion.setOnClickListener(
this
);
}
@Override
protected
boolean
toggleOverridePendingTransition() {
return
false
;
}
@Override
protected
TransitionMode getOverridePendingTransitionMode() {
return
null
;
}
@Override
protected
void
createPresenter() {
mPresenter =
new
MainPresenterImpl();
}
@Override
public
void
showError(String msg) {
}
@Override
public
void
useNightMode(
boolean
isNight) {
}
@Override
public
void
showUpdateDialog(VersionBean bean) {
}
@Override
public
void
showProgressDialog() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public
void
DissProgressDialog() {
progressBar.setVisibility(View.GONE);
}
@Override
public
void
ShowToast(String message) {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
@Override
public
void
onClick(View view) {
try
{
PackageManager pm = getPackageManager();
PackageInfo pi = pm.getPackageInfo(getPackageName(), PackageManager.GET_ACTIVITIES);
String versionName = pi.versionName;
mPresenter.checkVersion(versionName);
}
catch
(PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
}
|
再贴一下布局文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<RelativeLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"#ffffff"
>
<include
android:id=
"@+id/toolbar"
layout=
"@layout/view_toolbar"
/>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/recycleView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_below=
"@+id/toolbar"
android:visibility=
"gone"
>
</android.support.v7.widget.RecyclerView>
<Button
android:id=
"@+id/btn_getVersion"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerHorizontal=
"true"
android:layout_marginTop=
"400dp"
android:text=
"检查版本"
/>
<ProgressBar
android:id=
"@+id/progressBar"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerInParent=
"true"
android:visibility=
"gone"
/>
</RelativeLayout>
|
build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
apply plugin:
'com.android.application'
apply plugin:
'com.neenbedankt.android-apt'
android {
compileSdkVersion
25
buildToolsVersion
"25.0.0"
defaultConfig {
applicationId
"com.qianmo.myview2"
minSdkVersion
15
targetSdkVersion
25
versionCode
1
versionName
"1.0"
}
buildTypes {
release {
minifyEnabled
false
proguardFiles getDefaultProguardFile(
'proguard-android.txt'
),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir:
'libs'
, include: [
'*.jar'
])
testCompile
'junit:junit:4.12'
compile
'com.android.support:appcompat-v7:25.0.0'
compile
'com.android.support:design:25.+'
compile
'com.android.support:recyclerview-v7:25.+'
compile
'com.android.support:cardview-v7:25.+'
compile
'com.balysv:material-ripple:1.0.2'
compile
'com.jakewharton:butterknife:8.2.1'
apt
'com.jakewharton:butterknife-compiler:8.2.1'
compile
'io.reactivex:rxjava:1.1.0'
compile
'io.reactivex:rxandroid:1.1.0'
compile
'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile
'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile
'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile
'com.google.code.gson:gson:2.6.2'
}
|
好了,这样我们就把MVP简单的封装了,有没有很简单啊,下一篇接着封装Retrofit+Rxjava+Dagger。
see you next time·······