MVP+Retrofit+RxJava简单事例
【摘要】
早都想撸一个demo出来总结一下加深理解的,也想搞的深入一点,但是发现越深入反而越不好总结,只好先作罢,所以目前本文只是简单事例(大佬跳过)。
MVP
简化Activity,以接口的方式实现M层...
早都想撸一个demo出来总结一下加深理解的,也想搞的深入一点,但是发现越深入反而越不好总结,只好先作罢,所以目前本文只是简单事例(大佬跳过)。
MVP
简化Activity,以接口的方式实现M层和V层的交互,所以在定义接口前一定要先想好业务逻辑,这样接口写起来也比较便捷,不然的话就是写着写着,诶少个接口啊,然后回来又写个接口,这样的情况一次还好,一多就影响开发效率了。
Retrofit
其实是对OkHttp的封装,官网是这样介绍的:A type-safe HTTP client for Android and Java。一个类型安全的用于Android和Java网络请求的客户端。
RxJava
异步、简洁,链式的写法使逻辑看起来更加清晰。
以上只是简单总结,文末附详细链接
本文也是以GitHubApi为例子
先加依赖
/*retrofit*/
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
- 1
- 2
- 3
- 4
- 5
- 6
1、定义接口(View)
先想一下业务逻辑,获取数据然后展示数据,为了更好的用户体验,再加上Progress,联网的请求,然后还得有成功和失败的反馈,差不多先这些。
public interface MainView {
void showProgress();
void setDataList(List<Contributor> dataList);
void hideProgress();
void getDataByError();
void getDataBySuccess();
void httpError();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
获取数据我是直接放在点击事件了,应该再写一个getDataList的。
然后MainActivity实现MainView,接口方法都有了,就差数据了。View层是通过Presenter与Model层交互的,先写Model拿数据,再写Presenter把二者一连接,诶就好了。
2、获取数据(Model)
Model就比较简单了,因为只有一个获取数据的方法
public interface MainModel {
void getGitHubData(String userName, String repo, MainModelImpl.OnMainListener listener, Context context);
}
- 1
- 2
- 3
- 4
- 5
public class MainModelImpl implements MainModel {
@Override
public void getGitHubData(String userName, String repo, final OnMainListener listener, Context context) {
//rxjava方式
CompositeSubscription mSubscriptions = new CompositeSubscription();
mSubscriptions.add(
GitHubService.createRetrofitService(API.GitHubApi.class).contributorsByRxJava(userName, repo)//传两个参数到接口
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Contributor>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
listener.onError();
}
@Override
public void onNext(List<Contributor> contributors) {
for (Contributor c : contributors) {
Log.d("TAG", "login:" + c.getLogin() + " contributions:" + c.getContributions());
}
listener.onSuccess();
listener.setData(contributors);
}
}));
//一般请求
// API.GitHubApi gitHubApi = GitHubService.createRetrofitService(API.GitHubApi.class);
// Call<List<Contributor>> call = gitHubApi.contributorsBySimpleGetCall(userName, repo);
// call.enqueue(new Callback<List<Contributor>>() {
// @Override
// public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
// List<Contributor> contributorList = response.body();
// for (Contributor c : contributorList){
// Log.d("TAG", "login:" + c.getLogin() + " contributions:" + c.getContributions());
// }
// listener.onSuccess();
// listener.setData(contributorList);
// }
//
// @Override
// public void onFailure(Call<List<Contributor>> call, Throwable t) {
// listener.onError();
// }
// });
}
public interface OnMainListener {
void onError();
void onSuccess();
void onHttpError();
void setData(List<Contributor> dataList);
}
}
- 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
诶,这里用到了网络请求,所以再来搞一下http
public class API {
public interface GitHubApi {
//请求头 key value的形式
@Headers({
"name:request header"
})
@GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
//@Path:URL占位符,用于替换和动态更新,相应的参数必须使用相同的字符串被@Path进行注释,就是调用这个方法时动态传的参数
@GET("repos/{owner}/{repo}/contributors")
Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner, @Path("repo") String repo);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
public class GitHubService {
//初始化retrofit
public static <T> T createRetrofitService(final Class<T> service) {
//配置okhttp并设置时间和日志信息
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(15, TimeUnit.SECONDS)
.build();
//关联okhttp并加上rxjava和gson的配置和baseurl
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://api.github.com/")
.build();
return retrofit.create(service);
}
}
- 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
然后贴一下bean
public class Contributor {
private String login;
private Integer contributions;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public Integer getContributions() {
return contributions;
}
public void setContributions(Integer contributions) {
this.contributions = contributions;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
3、连接M层与V层(Presenter)
也是只有获取数据的方法
public interface MainPresenter {
void getData(String userName, String repo);
}
- 1
- 2
- 3
- 4
- 5
public class MainPresenterImpl implements MainPresenter, MainModelImpl.OnMainListener {
private MainView mMainView;
private MainModelImpl mMainModel;
private Context mContext;
public MainPresenterImpl(MainView view, Context context) {
this.mContext = context;
mMainView = view;
mMainModel = new MainModelImpl();
}
@Override
public void getData(String userName, String repo) {
if (mMainView != null) {
mMainView.showProgress();
}
//通过Model去获取数据
mMainModel.getGitHubData(userName, repo, this, mContext);
}
@Override
public void onError() {
if (mMainView != null) {
mMainView.getDataByError();
}
}
@Override
public void onSuccess() {
if (mMainView != null) {
mMainView.getDataBySuccess();
}
}
@Override
public void onHttpError() {
}
@Override
public void setData(List<Contributor> dataList) {
if (mMainView != null) {
mMainView.setDataList(dataList);
}
}
}
- 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
最后再来看一下MainActivity的代码
public class MainActivity extends AppCompatActivity implements MainView {
private String mUserName;
private String mRepo;
private TextView mTextView;
private ProgressDialog pd;
private MainPresenterImpl mMainPresenterImpl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUserName = getResources().getString(R.string.user_name);
mRepo = getResources().getString(R.string.repo);
mTextView = findViewById(R.id.text);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//获取MainPresenter,并通过MainPresenter获取数据
mMainPresenterImpl = new MainPresenterImpl(MainActivity.this, MainActivity.this);
mMainPresenterImpl.getData(mUserName, mRepo);
}
});
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("请求中");
}
@Override
public void showProgress() {
if (!pd.isShowing()) {
pd.show();
}
}
@Override
public void setDataList(List<Contributor> dataList) {
mTextView.setText(dataList.toString());
}
@Override
public void hideProgress() {
if (pd != null && pd.isShowing()) {
pd.dismiss();
}
}
@Override
public void getDataByError() {
hideProgress();
Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
}
@Override
public void getDataBySuccess() {
hideProgress();
Toast.makeText(MainActivity.this, "请求成功", Toast.LENGTH_SHORT).show();
}
@Override
public void httpError() {
hideProgress();
}
}
- 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
现在MainActivity看起来就比较清晰了。实际项目中很多都是可以进一步封装的,比如showProgress是很多页面都会有的,就可以再抽一下。
按照这个流程走下来是没有问题的,用到什么写什么,可能你一开始就把http给配置好了,这个是没有什么问题的,但是一开始就写太多东西的话,后面实际用到的时候如果不是一开始想的那样,又得重新写或者改了,这是影响效率的,所以何不一步一步脚踏实地呢对吧。
Demo地址:https://github.com/yechaoa/RxJavaRetrofitMVPDemo
相关资料
MVP:Android MVP模式实战
Retrofit:Retrofit2.0使用详解
RxJava: RxJava图文详解,可以说是很全了。
文章来源: blog.csdn.net,作者:yechaoa,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/yechaoa/article/details/77924063
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)