MVP+Retrofit+RxJava简单事例

简介: MVP+Retrofit+RxJava简单事例

早都想撸一个demo出来总结一下加深理解的,也想搞的深入一点,但是发现越深入反而越不好总结,只好先作罢,所以目前本文只是简单事例(大佬跳过)。

MVP

简化Activity,以接口的方式实现M层和V层的交互,所以在定义接口前一定要先想好业务逻辑,这样接口写起来也比较便捷,不然的话就是写着写着,诶少个接口啊,然后回来又写个接口,这样的情况一次还好,一多就影响开发效率了。


Retrofit

其实是对OkHttp的封装,官网是这样介绍的:A type-safe HTTP client for Android and Java。一个类型安全的用于Android和Java网络请求的客户端。


RxJava

异步、简洁,链式的写法使逻辑看起来更加清晰。


以上只是简单总结,文末附详细链接

本文也是以GitHubApi为例子

image.png


先加依赖

/*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、定义接口(View)

先想一下业务逻辑,获取数据然后展示数据,为了更好的用户体验,再加上Progress,联网的请求,然后还得有成功和失败的反馈,差不多先这些。


public interface MainView {
    void showProgress();
    void setDataList(List<Contributor> dataList);
    void hideProgress();
    void getDataByError();
    void getDataBySuccess();
    void httpError();
}

获取数据我是直接放在点击事件了,应该再写一个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);
}

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);
    }
}

诶,这里用到了网络请求,所以再来搞一下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);
    }
}
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);
    }
}

然后贴一下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;
    }
}

3、连接M层与V层(Presenter)

也是只有获取数据的方法


public interface MainPresenter {
    void getData(String userName, String repo);
}

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);
        }
    }
}

最后再来看一下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();
    }
}

现在MainActivity看起来就比较清晰了。实际项目中很多都是可以进一步封装的,比如showProgress是很多页面都会有的,就可以再抽一下。

按照这个流程走下来是没有问题的,用到什么写什么,可能你一开始就把http给配置好了,这个是没有什么问题的,但是一开始就写太多东西的话,后面实际用到的时候如果不是一开始想的那样,又得重新写或者改了,这是影响效率的,所以何不一步一步脚踏实地呢对吧。



目录
相关文章
|
11月前
|
JSON 缓存 前端开发
鸿蒙开发之网络框架搭建,MVP+Retrofit2+okhttp3+Rxjava2+RxHarmony2
鸿蒙开发之网络框架搭建,MVP+Retrofit2+okhttp3+Rxjava2+RxHarmony
286 1
|
11月前
|
JSON 缓存 前端开发
打造终极MVP+Retrofit2+okhttp3+Rxjava2网络请求,开发实用,简约2
打造终极MVP+Retrofit2+okhttp3+Rxjava2网络请求,开发实用,简约
198 0
|
11月前
|
缓存 JSON 网络协议
打造终极MVP+Retrofit2+okhttp3+Rxjava2网络请求,开发实用,简约1
打造终极MVP+Retrofit2+okhttp3+Rxjava2网络请求,开发实用,简约
225 0
|
前端开发 数据库 Android开发
一文带你玩转安卓Kotlin+Retrofit+RxJava+MVP架构(附Demo)
一文带你玩转安卓Kotlin+Retrofit+RxJava+MVP架构
253 0
一文带你玩转安卓Kotlin+Retrofit+RxJava+MVP架构(附Demo)
|
JSON Java 数据格式
rxjava2+retrofit2 简介
rxjava2+retrofit2 简介
79 0
|
Java 调度 安全
Rxjava深入理解之自己动手编写Rxjava
Demo的源码地址在 mini-rxjava, 有兴趣的可以下载源码来看. 从观察者模式说起 观察者模式,是我们在平时使用的比较多的一种设计模式.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
1153 0
|
Java API Android开发
带实际例子的Android架构MVP简述一「 JAVA,MVP,Retrofit,RxJava」
带实际例子的Android架构MVP简述一「 JAVA,MVP,Retrofit,RxJava」 谷歌推荐的MVP架构,是有Model层的。但是也有一种方式,是省略了Model层,把网络请求的方式在Presenter层完成了。
1454 0
|
Android开发 数据格式 JSON
【Android架构】基于MVP模式的Retrofit2+RXjava封装之常见问题(四)
先回顾下之前的 【Android架构】基于MVP模式的Retrofit2+RXjava封装(一)【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件下载(二)【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件上传(三) 今天要说的是使用Retrofit2和Okhttp 过程中遇到的一些问题。
1070 0
|
Android开发
【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件上传(三)
最近手头事比较多,抽个空把之前系列也补充一下。 先回顾下之前的 【Android架构】基于MVP模式的Retrofit2+RXjava封装(一)【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件下载(二) 今天要说的是文件上传 1.
3395 0