Android Development: MVI, why can simply be more complicated?

Detailed

These days the overwhelming Nuggets MVI, but read are written by mosby, I felt fee starting mosby it? PublishSubject simple can be achieved, examples in this article is changed in the previous code, using java forgive me, welcome addition spray, do not spray uncomfortable Ha ...

MVI concept

MVI is a concept and MVVM appear together, the idea is to follow Rxjava responsive ideas derived from

MVVM I guess we are all familiar, the data layer transfer Livedata -> persenter -> UI layer and then to register the listener, this is a one-way process, from data -> the UI process:

General MVVM We are all so written, but some people writing more thorough, app interaction is a two-way process, starting with the UI -> Data then Data -> UI, just above the common way we achieve the one side, a more thorough responsive transformation is even click events are responsive, the data layer button click event listener registered to receive data via Sheung Shui pipeline, remote data return and then return the data through the sewer pipe:

General did not write too much trouble -

MVI and two-way MVVM same idea, the difference is MVI further action UI abstraction, that is, MVI in I - Intent, MVI in to any of the UI events are seen as a responsive data source, the task is to bind layer P V and M relations registration layer, just as heater turned down the water pipe:

MVI in this Intent have their own thoughts, any changes in the UI page Intent are as a whole, with a data type to represent, for example, there is a ViewState objects inside loading, netError, success represents the various flag state of the page , returns the data layer rather than directly ViewState of data, UI UI layer to display different patterns, so that a pile P layer do not write control method of the UI display state according to the state of ViewState, truly MVP the hierarchical thinking, who cares who the things, of course, can do MVVM, MVVM but generally there is a direct return data, really put the package into the data page status also not many people

class NetViewState(
        var loading: Boolean = false,
        var success: Boolean = false,
        var netError: Boolean = false,
        var dataError: Boolean = false,
        var dataNo: Boolean = false,
        var message: String = "",
        var data: BookResponse = BookResponse()) {

    companion object Help {

        @JvmStatic
        fun loading(): NetViewState {
            return NetViewState(loading = true)
        }

        @JvmStatic
        fun success(data: BookResponse): NetViewState {
            return NetViewState(success = true, data = data)
        }

        @JvmStatic
        fun netError(message: String): NetViewState {
            return NetViewState(netError = true, message = message)
        }

        @JvmStatic
        fun dataError(message: String): NetViewState {
            return NetViewState(dataError = true, message = message)
        }

        @JvmStatic
        fun dataNo(message: String): NetViewState {
            return NetViewState(dataNo = true,message = message)
        }
    }
}

Code to go from

MVI I read a lot of articles, are achieved by means of mosby this library, mosby brought a lot of derivative type, each character has its base class, virtually greatly increased learning costs, MVI is this idea further MVVM it did not expect everyone to do but rather more complex, no need to finish the whole, simple good, but also easy to understand, easy to read

Use rxjava thermal emission or Livedata can simply achieve MVI, and I do not want to use mosby, out of their own to achieve a MVI, following Demo only demonstrates a more introspective please package, optimization

Ui layers provide external events Intent

protected void onCreate(Bundle savedInstanceState) {
        btn_book.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bookIntent.onNext(new BookRequest("人生", "", "0", "10"));
            }
        });

        persenter.netActivity = this;
        persenter.bingIntent(bookIntent);
    }

    void updata(NetViewState netViewState) {

        if (netViewState.getLoading()) {
            Log.d("AA", "loading ...");
            return;
        }

        if (netViewState.getNetError()) {
            Log.d("AA", " netError:" + netViewState.getMessage());
        }

        if (netViewState.getDataError()) {
            Log.d("AA", " dataError:" + netViewState.getMessage());
        }

        if (netViewState.getSuccess()) {
            List<BookResponse.Book> books = netViewState.getData().getBooks();
            if (books != null && books.size() == 0) {
                ToastComponent.Companion.getInstance().show("没有数据", Toast.LENGTH_SHORT);
            }
            adapter.refreshData(books);
        }
    }

M level attention event upstream of the UI layer, the data layer is provided downstream of the viewer

public class BookRepositroy {

    public static final String URL_BOOK_LIST = "book/search";
    public PublishSubject<NetViewState> bookData = PublishSubject.create();

    public void bingIntent(Observable<BookRequest> bookIntent) {
        bookIntent.subscribe(new Consumer<BookRequest>() {
            @Override
            public void accept(BookRequest bookRequest) throws Exception {
                getBookData(bookRequest);
            }
        });
    }

    private void getBookData(BookRequest bookRequest) {

        Map<String, String> map = new HashMap<>();
        map.put("q", bookRequest.getTitle());
        map.put("tag", bookRequest.getTag());
        map.put("start", bookRequest.getStartCount());
        map.put("count", bookRequest.getWantCount());

        HttpClient.Companion.getInstance().get(URL_BOOK_LIST, map)
                .map(new Function<ResponseBody, NetViewState>() {
                    @Override
                    public NetViewState apply(ResponseBody responseBody) throws Exception {
                        BookResponse bookResponse = null;
                        try {
                            bookResponse = new Gson().fromJson(responseBody.string(), BookResponse.class);
                        } catch (Exception e) {
                            Observable.error(e);
                        }
                        return NetViewState.success(bookResponse);
                    }
                })
                .onErrorReturn(new Function<Throwable, NetViewState>() {
                    @Override
                    public NetViewState apply(Throwable throwable) throws Exception {

                        if (throwable instanceof HttpException) {
                            // HTTP错误
                            return NetViewState.netError("网络错误");
                        } else if (throwable instanceof ConnectException
                                || throwable instanceof UnknownHostException) {
                            // 连接错误
                            return NetViewState.netError("连接错误");
                        } else if (throwable instanceof InterruptedIOException) {
                            // 连接超时
                            return NetViewState.netError("连接超时");
                        } else if (throwable instanceof JsonParseException
                                || throwable instanceof JSONException
                                || throwable instanceof ParseException) {
                            return NetViewState.dataError("解析错误");
                        } else if (throwable instanceof ApiException) {
                            return NetViewState.netError(throwable.getMessage());
                        } else if (throwable instanceof IOException) {
                            return NetViewState.netError("网络错误");
                        }
                        return NetViewState.netError("位置错误");
                    }
                })
                .startWith(NetViewState.loading())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Consumer<NetViewState>() {
                    @Override
                    public void accept(final NetViewState netViewState) throws Exception {
                        bookData.onNext(netViewState);
                    }
                });
    }
}

Binding p-layer downstream (V and P) relationship

public class NetPersenter {

    public NetActivity netActivity;
    BookRepositroy repositroy = new BookRepositroy();

    public void bindBook(PublishSubject<BookRequest> bookIntent) {

        repositroy.bingIntent(bookIntent);
        repositroy.bookData.subscribe(new Consumer<NetViewState>() {
            @Override
            public void accept(NetViewState netViewState) throws Exception {
                netActivity.updata(netViewState);
            }
        });
    }
}

Thinking:

  • P layer without registration downstream data to layer V, P layer on the inside because we might have business logic to a deal with first, not directly to the U layer
  • M layer using startWith priority to send out a loading event
  • ViewState here can be further optimized, most of the state are the same page, there is a need to abstract base class out, and the use of koltin sealed class (sealed) can do better, say now is the era of the kotlin, pure java I posted the code should not be, this is because the page was written before the above change, or I'll kotlin the

At last

Not a few lines of code, it would have been not intend to write the article came out, but then think about online libraries are used mosby written MVI, I write to provide you another idea of ​​it, can simply why it is more complicated


In this I also share a big brother himself included finishing the Android architecture study PDF + Video + Interview + document source notes , as well as advanced technical architecture Advanced Brain Mapping, Android interview with thematic development, senior advanced information architecture these are my leisure boutique will be repeated read data. In the mind map, each point is equipped with a knowledge of the topic corresponding to the actual project, can effectively help you grasp the knowledge points.

In short we are also here to help enhance learning advanced, but also saves you the time to learn online search data can also be shared with close friends studying together

If you have a need, you can point like + comment , concern me , plus Vx: 15388039515 (Note CSDN, need more advanced data)

Published 200 original articles · won praise 83 · views 70000 +

Guess you like

Origin blog.csdn.net/weixin_45258969/article/details/104419790