A small test of Android RxJava+Retrofit2.0+MVP

This article mainly introduces the use of Android Rxjava and Retrofit in the MVP design pattern.
Rxjava encapsulates asynchronous operations. There is no need to write annoying Handler. AsyncTask makes the code more concise and clearer. The more complex the program logic, Rxjava can be more effective.
Retrofit is an open source library
MVP design pattern that encapsulates network operations. It makes each module of the program perform its own duties without interfering with each other. The
View layer is responsible for interacting with the user, and the logic processing does not matter. The
Model layer is responsible for logic processing. Just make dried radishes for you, and make Korean kimchi
for you when you come with cabbage. Presenter is mainly responsible for connecting Model and View. My understanding is porter. Presenter gives Model and Model the radish sent by View (Activity). The dried radish is returned to View through Presenter

The reason is very simple, and I can say it, but it is really rare to realize it. MVP is a rare idea. The definition of the interface and the callback of the method are relatively abstract. This requires continuous learning, writing and reading.

I will not introduce the two open source libraries Rxjava and Retrofit separately here. There are a lot of blogs on the Internet.

Students who want to learn Rxjava can enter http://gank.io/post/560e15be2dca930e00da1083

For students who want to learn Retrofit, please see this http://square.github.io/retrofit/

The following describes how to use the official start RxJava + Retrofit2.0 + MVP implement a network request

First of all, the need to use open source libraries to engage in build.gradle down, this example will be used in

retrofit, Rxjava, okhttp, RxAndroid, Gson, SmartRefreshLayout, glide these open source libraries
compile 'com.android.support:appcompat-v7:25.3.1'

compile 'com.android.support:recyclerview-v7:23.4.0'

compile 'com.squareup.retrofit2:retrofit:2.3.0' 

compile 'com.squareup.retrofit2:converter-gson:2.0.2'

compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.okhttp3:okhttp:3.3.1' 网络请求的,retrofit主要是封装了请求操作,网络获取数据还是靠okhttp

compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.3'

compile 'io.reactivex:rxandroid:1.1.0'

compile 'com.github.bumptech.glide:glide:4.0.0'

The required open source libraries are ready, and then you can start working. Now that the mvp design pattern is used, you can't start writing code in the activity as usual. You have to type up the architecture first, and then fill in the content slowly, just like building a house, step by step. Build the package first, this is free to play, there is no fixed mode, it seems to be clear at a glance, don’t find a category later for a long time, don’t know which package it is in, you have to look at it one by one.


After the package is built, the design will begin below, and the code is not in a hurry.

First of all, we must know what we want to do, what functions need to be implemented, and what to achieve.

We want to access the Internet, load data from the Internet, display it on the street, and use mvp mode to implement it with some open source libraries

Well, know what to do, know what method to use, and then it will be easy to do. In many cases, the difficulty is that we don’t know what to do.

Obtaining data, such a complicated operation cannot be implemented in the activity. Originally, it was annoying for people to interact with the user, and he left such troublesome things to him. Something might happen later, so let the model do it, but Hand it over to the model, how to give the obtained data to the view, this requires us to design the interface, return the data to the persenter through the callback method, and pass it to the view through the persenter to achieve the model layer and the view as much as possible Decoupling

Model



First define two IModle interfaces

package modle.Impl;

import java.util.List;

import bean.Book;

/**
 * Created by Administrator on 2017/9/7.
 */

public interface IBookModle extends IModle{
    void getBook(AsyncCallback callback,String name,int start,int count);
}


package modle.Impl;

/**
 * Created by limeng on 2017/9/7.
 */

public interface IModle {
     public interface AsyncCallback {

        void onSuccess(Object success);

        void onError(Object error);
    }
}
Since it is to get data, there needs to be a method to get the data, through the getBook method to get the data, the AsyncCallback parameter is the parameter that will be passed when the callback is called, the name of the book is the name of the book, and the start is from that data. count is how many data to get

package modle;

import android.util.Log;

import com.google.gson.Gson;


import bean.Book;
import impl.ApiService;
import modle.Impl.IBookModle;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * Created by limeng on 2017/9/7.
 */

public class BookModle implements IBookModle {
    private Retrofit mRetrofit;
    private ApiService request;
    @Override
    public void getBook(final AsyncCallback callback, String name, int start, int count) {
        mRetrofit = new Retrofit.Builder()
                .baseUrl("https://api.douban.com/v2/") // 设置
                .addConverterFactory(GsonConverterFactory.create(new Gson())) // 设置使用Gson解析(记得加入依赖)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        // 步骤5:创建 网络请求接口 的实例
        request = mRetrofit.create(ApiService.class);
        // 对 发送请求 进行封装
        request.getCall(name, null, start, count)
                .subscribeOn(Schedulers.newThread())
                .doOnNext(new Action1<Book>() {
                    @Override
                    public void call(Book bean) {
                        Log.e("limeng", "doOnNext" + Thread.currentThread().getName());
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Book>() {
                    @Override
                    public void call(Book book) {
                        callback.onSuccess(book);
                    }

                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        callback.onError(throwable);
                    }
                });
    }
}
Define a modelBook class to implement IModelBook, rewrite its getBook method, and then get the data. When the request is successful, pass the callback callback callback.onSuccess(book) through persenter; then persenter gets the data, and when the request fails, callback.onError (throwable);

the centerpiece

The same is to define the interface first

package presenter;

/**
 * Created by Administrator on 2017/9/6.
 */

public interface IBookPresenter {
    void loadBook(String name,int start,int count);
}
This is used to load data. In fact, the method name should be replaced with model. Model is to load data, and persenter is to get data.

package presenter.Impl;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import java.util.List;

import bean.Book;
import modle.BookModle;
import modle.Impl.IBookModle;
import modle.Impl.IModle;
import presenter.IBookPresenter;
import view.IBookView;

/**
 * Created by limeng on 2017/9/6.
 */

public class BookPresenter implements IBookPresenter{
    private IBookModle modle;
    private IBookView mBookView;
    public BookPresenter(IBookView view){
        mBookView=view;
        modle=new BookModle();
    }
    @Override
    public void loadBook(String name,int start,int count) {
        modle.getBook(new IModle.AsyncCallback() {
            @Override
            public void onSuccess(Object success) {
                Book book= (Book) success;
                mBookView.upDataBookList(book);
            }
            @Override
            public void onError(Object error) {
                Throwable throwable= (Throwable) error;
                Log.e("limeng","throwable="+throwable.toString());
                Toast.makeText((Context) mBookView,"加载数据失败",Toast.LENGTH_LONG).show();
            }
        },name,start,count);
    }
}

Create a BookPresenter class to implement the interface, rewrite the loadBook method, and get a structured correspondence to receive the view, create an instance of the model, and then call the getBook method of the model in the loadBook method, new an AsyncCallback object, and rewrite his
onSuccess(),
onError()方法,这样就获取到了返回的数据,同时还要传递书名name,start,count,这三个参数就是你想要获取到什么样的数据



View

没得说,先定义接口

package view;

import java.util.List;

import bean.Book;

/**
 * Created by Administrator on 2017/9/7.
 */

public interface IBookView {
    void upDataBookList(Book book);
}

Define an IBookView interface, the upDataBookList in it is mainly to update the interface through the obtained data

package com.limeng.ke.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;

import java.util.List;

import adapter.RecyAdapter;
import bean.Book;
import fragment.MyFragment;
import presenter.IBookPresenter;
import presenter.Impl.BookPresenter;
import view.IBookView;


public class MainActivity extends Activity implements View.OnClickListener, MyFragment.LogLinsenter, IBookView {
    private Button btnLoadData;//点击加载数据
    private Button btnDelete;//删除数据
    private Button btnAdd;//添加数据

    private RefreshLayout mRefreshLayout;
    private RecyclerView mRecyclerView;
    private SmartRefreshLayout smartRefreshLayout;
    private RecyAdapter mAdapter = null;

    private Book book = null;
    private IBookPresenter mPresenter;
    private List<Book.BooksBean> mBoosBeanList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//      initData();
        initView();
        mPresenter = new BookPresenter(MainActivity.this);
        initData();
        initAdapter();
    }

    private void initData() {

    }

    private void initAdapter() {

    }

    private void initView() {
//        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mRefreshLayout = (RefreshLayout) findViewById(R.id.smartRefreshLayout);
        btnLoadData = (Button) findViewById(R.id.iv_Pic1);
        btnDelete = (Button) findViewById(R.id.btn_delete);
        btnAdd = (Button) findViewById(R.id.btn_add);
        btnLoadData.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
        btnAdd.setOnClickListener(this);
//        Glide.with(MainActivity.this).load(Images.imageUrls[0]).into(ivPic1);
        mRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(RefreshLayout refreshlayout) {
                int start = book.getStart();
                int count = book.getCount();
                //向下拉刷新
                Log.e("limeng", "正在刷新--------->start=" + start);
                Log.e("limeng", "正在刷新--------->count=" + count);
                refreshlayout.finishRefresh(5000);
            }

        });
        mRefreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() {
            @Override
            public void onLoadmore(RefreshLayout refreshlayout) {
                //向上拉加載更多
                refreshlayout.finishLoadmore(5000);
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_Pic1:
                mPresenter.loadBook("金瓶梅", 0, 10);
                break;
            case R.id.btn_add:
                mAdapter.addData(1);
                break;
            case R.id.btn_delete:
                mAdapter.removeData(1);
                break;
        }
    }

    @Override
    public void log(String name) {
    }

    @Override
    public void upDataBookList(Book book) {
        Log.e("limeng", "upDataBookList");
        this.book=book;
        mBoosBeanList = book.getBooks();
        RecyAdapter adapter = new RecyAdapter(MainActivity.this, mBoosBeanList);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));//这里用线性显示 类似于listview
        mRecyclerView.setAdapter(adapter);
    }
}
The activity implements the IBookView interface, overrides the unDataBookList method, and instantiates a presenter object. The user wants to get data through a click event, clicks the button, and calls

mPresenter.loadBook("金瓶梅", 0, 10); this method through the presenter object . The model instance in the presenter will be triggered to call the getBook method, and then the getBook method in the trigger model will get the data, and

the data will be called back to the presenter through the onSuccess() and onError() methods in the AsyncCallback interface. In the presenter, the IBookview interface is used. In the
mBookView.upDataBookList(book); method, the data is called back to the activity, and finally the activity rewrites the upDataBookList(book) method to obtain the data and
finally realizes the view sending instruction, passes it to the model through the presenter, and the model processes the logic, and returns the data through the presenter For the activity, the logical data layer and the View are perfectly decoupled, the code is clearer, easier to read, and it is also conducive to the later maintenance of the code

















最后附上demo代码http://download.csdn.net/download/u010471406/9970769









Guess you like

Origin blog.csdn.net/u010471406/article/details/77899269